package edu.pw.p2pclient.activities;

import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

class MyLocationListener implements LocationListener {

	private static final int TWO_MINUTES = 1000 * 60 * 2;
	protected Location mCurrentLocation = null;
	private LocationManager mLocationManager;
	private boolean mLocationEnabled = false;

	public MyLocationListener(LocationManager manager) {
		mLocationManager = manager;
	}

	public Location getCurrentLocation() {
		return mCurrentLocation;
	}

	public boolean isLocationEnabled() {
		return mLocationEnabled;
	}

	@Override
	public void onLocationChanged(Location location) {
		if (isBetterLocation(location, mCurrentLocation)) {
			mCurrentLocation = location;
		}
	}

	@Override
	public void onStatusChanged(String provider, int status, Bundle extras) {
		// TODO Auto-generated method stub
	}

	private boolean isBetterLocation(Location location,
			Location currentBestLocation) {
		if (location == null)
			return false;
		if (currentBestLocation == null)
			return true;

		// Check whether the new location fix is newer or older
		long timeDelta = location.getTime() - currentBestLocation.getTime();
		boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
		boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
		boolean isNewer = timeDelta > 0;

		// If it's been more than two minutes since the current location,
		// use
		// the new location,
		// because the user has likely moved.
		if (isSignificantlyNewer)
			return true;
		else if (isSignificantlyOlder)
			return false;

		// Check whether the new location fix is more or less accurate
		int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
				.getAccuracy());
		boolean isLessAccurate = accuracyDelta > 0;
		boolean isMoreAccurate = accuracyDelta < 0;
		boolean isSignificantlyLessAccurate = accuracyDelta > 200;

		// Determine location quality using a combination of timeliness and
		// accuracy
		// @formatter:off
	    return (isMoreAccurate 
	    		|| isNewer && !isLessAccurate 
	    		|| isNewer && !isSignificantlyLessAccurate && isSameProvider(
	    				location.getProvider(), currentBestLocation.getProvider()));
	    // @formatter:on
	}

	private boolean isSameProvider(String provider1, String provider2) {
		if (provider1 == null)
			return provider2 == null;
		return provider1.equals(provider2);
	}

	@Override
	public void onProviderEnabled(String provider) {
		Log.i(RequestActivity.TAG, provider + " enabled.");
		mLocationEnabled = mLocationManager
				.isProviderEnabled(LocationManager.GPS_PROVIDER)
				|| mLocationManager
						.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
	}

	@Override
	public void onProviderDisabled(String provider) {
		Log.i(RequestActivity.TAG, provider + " disabled.");
		mLocationEnabled = mLocationManager
				.isProviderEnabled(LocationManager.GPS_PROVIDER)
				|| mLocationManager
						.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
	}

}